"""
Case Type   : ustore_DQL_SET_OPERATIONS
Case Name   : trim/substr/length函数结合union
Create At   : 2022-05-12
Owner       : nanyang12
Description :
    1.创建表
    2.使用copy命令插入数据
    3.trim/substr/length/函数结合union
    4.环境清理
Expect      :
    1.创建成功
    2.数据插入成功
    3.成功
    4.清理成功
History     :
"""

import os
import subprocess
import unittest

from testcase.utils.Common import Common
from testcase.utils.CommonSH import CommonSH
from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger
from yat.test import Node
from yat.test import macro


class Ustore01(unittest.TestCase):
    def setUp(self):
        self.log = Logger()
        self.log.info(f'----- {os.path.basename(__file__)} start-----')
        self.pri_sh = CommonSH('PrimaryDbUser')
        self.pri_root = Node('PrimaryRoot')
        self.com = Common()
        self.constant = Constant()
        self.table_name1 = 't_setop_Cast_0002_01'
        self.table_name2 = 't_setop_Cast_0002_02'
        self.table_name3 = 't_setop_Cast_0002_03'
        self.copy_file1 = 'customer_address_33.txt'
        self.copy_file2 = 'warehouse_33.txt'
        self.copy_file3 = 'customer_demographics_33.txt'
        self.cur_path_1 = os.path.join(macro.SCRIPTS_PATH, self.copy_file1)
        self.cur_path_2 = os.path.join(macro.SCRIPTS_PATH, self.copy_file2)
        self.cur_path_3 = os.path.join(macro.SCRIPTS_PATH, self.copy_file3)
        self.parent_path = os.path.dirname(macro.DB_INSTANCE_PATH)
        self.target_path1 = os.path.join(self.parent_path, self.copy_file1)
        self.target_path2 = os.path.join(self.parent_path, self.copy_file2)
        self.target_path3 = os.path.join(self.parent_path, self.copy_file3)

    def test_join(self):
        step_txt = '-----step1:创建表;expect: 创建成功-----'
        self.log.info(step_txt)
        cmd_sql = f"""drop table if exists {self.table_name1}  CASCADE ;
                    drop table if exists {self.table_name2}  CASCADE ;
                create table {self.table_name1}(
                    ca_address_sk             integer               not null,
                    ca_address_id             char(16)              not null,
                    ca_street_number          char(10)                      ,
                    ca_street_name            varchar(60)                   ,
                    ca_street_type            char(15)                      ,
                    ca_suite_number           char(10)                      ,
                    ca_city                   varchar(60)                   ,
                    ca_county                 varchar(30)                   ,
                    ca_state                  char(2)                       ,
                    ca_zip                    char(10)                      ,
                    ca_country                varchar(20)                   ,
                    ca_gmt_offset             decimal(5,2)                  ,
                    ca_location_type    char(20))  WITH (STORAGE_TYPE=USTORE);
                create table {self.table_name2}(
                    w_warehouse_sk            integer               not null,
                    w_warehouse_id            char(16)              not null,
                    w_warehouse_name          varchar(20)                   ,
                    w_warehouse_sq_ft         integer                       ,
                    w_street_number           char(10)                      ,
                    w_street_name             varchar(60)                   ,
                    w_street_type             char(15)                      ,
                    w_suite_number            char(10)                      ,
                    w_city                    varchar(60)                   ,
                    w_county                  varchar(30)                   ,
                    w_state                   char(2)                       ,
                    w_zip                     char(10)                      ,
                    w_country                 varchar(20)                   ,
                    w_gmt_offset              decimal(5,2)
                 ) WITH (STORAGE_TYPE=USTORE);
                drop table if exists {self.table_name3}  CASCADE ;
                create table {self.table_name3}
                (
                    cd_demo_sk                integer               not null,
                    cd_gender                 char(1)                       ,
                    cd_marital_status         char(1)                       ,
                    cd_education_status       char(20)                      ,
                    cd_purchase_estimate      integer                       ,
                    cd_credit_rating          char(10)                      ,
                    cd_dep_count              integer                       ,
                    cd_dep_employed_count     integer                       ,
                    cd_dep_college_count      integer                       
                )
                WITH (STORAGE_TYPE=USTORE) partition by range (cd_demo_sk)
                (
                partition customer_demographics_1 values less than (1000),
                partition customer_demographics_2 values less than (7700),
                partition customer_demographics_3 values less than (33700),
                partition customer_demographics_4 values less than (57300),
                partition customer_demographics_5 values less than (135700),
                partition customer_demographics_6 values less than (203300),
                partition customer_demographics_7 values less than (208700),
                partition customer_demographics_8 values less than (238700),
                partition customer_demographics_9 values less than (268700),
                partition customer_demographics_10 values less than (298700),
                partition customer_demographics_11 values less than (338700),
                partition customer_demographics_12 values less than (368700),
                partition customer_demographics_13 values less than (398700),
                partition customer_demographics_14 values less than (438700),
                partition customer_demographics_15 values less than (maxvalue)
                );"""
        self.log.info(cmd_sql)
        create_result = self.pri_sh.execut_db_sql(cmd_sql)
        self.log.info(create_result)
        self.assertTrue(
            create_result.count(self.constant.TABLE_CREATE_SUCCESS) == 3,
            '执行失败:' + step_txt)

        step_txt = '-----step2:使用copy命令插入数据，expect: 数据插入成功-----'
        self.log.info(step_txt)
        text = '-----step2.1: 获取当前主机的IP地址;expect: 成功-----'
        self.log.info(text)
        cmd = "ifconfig -a|grep inet6 -a2|grep broadcast|awk '{print $2}'"
        self.log.info(cmd)
        self.cur_ip = subprocess.getoutput(cmd).strip()
        self.log.info(self.cur_ip)

        text = '-----step2.2: 复制文件到数据库主机对应目录 expect: 成功-----'
        self.log.info(text)
        if self.cur_ip == self.pri_sh.node.ssh_host:
            self.log.info('当前主机是数据库主机，无需远程复制')
            cmd = f"cp {self.cur_path_1} {self.parent_path};" \
                f"cp {self.cur_path_2} {self.parent_path};" \
                f"cp {self.cur_path_3} {self.parent_path};"
            self.log.info(cmd)
            res = self.pri_sh.node.sh(cmd).result()
            self.log.info(res)
        else:
            self.com.scp_file(self.pri_root, self.copy_file1,
                              self.parent_path)
            self.com.scp_file(self.pri_root, self.copy_file2,
                              self.parent_path)
            self.com.scp_file(self.pri_root, self.copy_file3,
                              self.parent_path)
            chmod_cmd = f"chmod 777 -R {self.parent_path};" \
                        f"ls -al {self.parent_path}"
            self.log.info(chmod_cmd)
            chmod_result = self.pri_root.sh(chmod_cmd).result()
            self.log.info(chmod_result)

        text = '-----step2.3: 查看数据库主机目标路径下文件 expect: 成功-----'
        self.log.info(text)
        cmd = f"ls -l {self.parent_path}| grep -E '{self.copy_file1}';" \
            f"ls -l {self.parent_path}| grep -E '{self.copy_file2}';" \
            f"ls -l {self.parent_path}| grep -E '{self.copy_file3}'"
        self.log.info(cmd)
        res = self.pri_root.sh(cmd).result()
        self.log.info(res)
        self.assertNotIn('No such file or directory', res, '文件拷贝失败')
        self.assertIn(f'{self.copy_file1}', res, '文件拷贝失败')
        self.assertIn(f'{self.copy_file2}', res, '文件拷贝失败')
        self.assertIn(f'{self.copy_file3}', res, '文件拷贝失败')

        text = '-----step2.4:使用copy命令插入数据，expect: 数据插入成功-----'
        self.log.info(text)
        self.log.info('---------------使用copy命令插入数据------------------')
        copy_sql = f"copy {self.table_name1} from '{self.target_path1}' " \
            f"delimiters ',';" \
            f"copy {self.table_name2} from '{self.target_path2}' " \
            f"delimiters ',';" \
            f"copy {self.table_name3} from '{self.target_path3}'" \
            f"delimiters ',';"
        self.log.info(copy_sql)
        copy_result = self.pri_sh.execut_db_sql(copy_sql)
        self.log.info(copy_result)
        self.assertIn('COPY 50000', copy_result, '执行失败:' + step_txt)
        self.assertIn('COPY 5', copy_result, '执行失败:' + step_txt)
        self.assertIn('COPY 1920800', copy_result, '执行失败:' + step_txt)

        step_txt = '-----step3: trim/substr/length/函数结合union ' \
                   'expect: 成功-----'
        self.log.info(step_txt)
        cmd_sql = f"""
        select trim(cd_demo_sk,'2')from {self.table_name3}
        where substr(cd_demo_sk,2,5)=8251 and 
        length(trim(cd_education_status))='7' group by cd_demo_sk union 
        select '' from {self.table_name2} group by w_city order by 1;
        select trim(ca_address_sk,'2') from {self.table_name1} 
        where substr(ca_address_sk,2,4)=1825 group by ca_address_sk
        union select w_street_name from {self.table_name2} where 
        w_warehouse_sk=6  group by w_street_name order by 1;"""
        self.log.info(cmd_sql)
        query_result = self.pri_sh.execut_db_sql(cmd_sql)
        self.log.info(query_result)
        self.assertIn('9 rows', query_result, '执行失败:' + step_txt)
        self.assertIn('4 rows', query_result, '执行失败:' + step_txt)

    def tearDown(self):
        step_txt = '-----step4: 环境清理 expect:清理成功-----'
        self.log.info(step_txt)
        self.log.info('删除表')
        cmd_sql = self.pri_sh.execut_db_sql(f"""
                    drop table {self.table_name1} cascade;
                    drop table {self.table_name2} cascade;
                    drop table {self.table_name3} cascade;""")
        self.log.info(cmd_sql)
        text = '-----删除文件-----'
        self.log.info(text)
        rm_cmd = f"rm -rf {self.target_path1};" \
            f"rm -rf {self.target_path2};" \
            f"rm -rf {self.target_path3};"
        self.log.info(rm_cmd)
        self.com.get_sh_result(self.pri_root, rm_cmd)
        for s in [self.target_path1, self.target_path2, self.target_path3]:
            cmd = f'if [ -f {s} ]; then echo "does exists"; ' \
                f'else echo "not exists"; fi'
            file_judgments = self.com.get_sh_result(self.pri_root, cmd)
            self.assertIn('not exists', file_judgments, "清理失败" + text)
        self.assertTrue(
            cmd_sql.count(self.constant.DROP_TABLE_SUCCESS) == 3,
            '执行失败:' + step_txt)
        self.log.info(f'----- {os.path.basename(__file__)} end-----')

